package edu.pku.sei.transformation.editor.model.goal;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;

import edu.pku.sei.gefcommon.descriptor.annotation.ListProperty;
import edu.pku.sei.gefcommon.descriptor.annotation.MethodProperty;
import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.MetaTypedList;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.xml.XMLUtility;
import edu.pku.sei.transformation.editor.model.ModelFactory;
import edu.pku.sei.transformation.editor.model.ModelPackage;
import edu.pku.sei.transformation.editor.model.base.NamedElement;
import edu.pku.sei.transformation.editor.model.constraint.ConstraintConnection;
import edu.pku.sei.transformation.editor.model.constraint.IConstrainableElement;

public class TransformationGoal extends NamedElement implements IConstrainableElement{
	private boolean isOptional = false;
	private ArrayList<GoalRelationship> relationships = new ArrayList<GoalRelationship>();
	private ArrayList<ConstraintConnection> constraints = new ArrayList<ConstraintConnection>();
	//private ArrayList<DescriptionConnection> descriptions = new ArrayList<DescriptionConnection>();
	
	private Description goalDescription;
	private MetaTypedList endDescription = new MetaTypedList(Description.class, this, ModelPackage.REQUIREMENT_END_DESCRIPTION);
	public TransformationGoal() {
	}
	public Description getGoalDescription() {
		if (goalDescription == null) {
			try {
				ModelFactory f = (ModelFactory) ModelRegistry.getRegistry().getFactory(this.getModel());
				goalDescription = (Description) f.createElement(ModelPackage.__REQUIRE_DESCRIPTION__, true);
				goalDescription.setSummary("Goal Description");
				goalDescription.setContainer(this);
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (FactoryNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
			
		return goalDescription;
	}
	
	public void setGoalDescription(Description goalDescription) {
		this.goalDescription = goalDescription;
	}
	
	@MethodProperty(id = ModelPackage.REQUIREMENT_END_DESCRIPTION, name = "description", catalog = "Goal")
	@ListProperty(allowTypes = Description.class, newInstanceMethod = "newInstance", typeString = ModelPackage.__REQUIRE_DESCRIPTION__)
	public MetaTypedList getEndDescription() {
		return endDescription;
	}
	
	public boolean isOptional() {
		return isOptional;
	}

	public void setOptional(boolean isOptional) {
		this.isOptional = isOptional;
	}

	
	public List<GoalRelationship> getRelationships() {
		return relationships;
	}
	
//	public List<DescriptionConnection> getDescriptions() {
//		return this.descriptions;
//	}
	@Override
	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeNodes(root, ModelPackage.REQUIREMENT_RELATIONSHIPS, relationships);
		XMLUtility.xmlInstance.serializeNodes(root, ModelPackage.REQUIREMENT_CONSTRAINTS, constraints);
		XMLUtility.xmlInstance.serializeNode(root, ModelPackage.REQUIREMENT_GOAL_DESCRIPTION, this.goalDescription);
		XMLUtility.xmlInstance.serializeNodes(root, ModelPackage.REQUIREMENT_END_DESCRIPTION, this.endDescription);
	}
	
	@Override
	public void deSerialize(Element root) {
		super.deSerialize(root);
		relationships.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ModelPackage.REQUIREMENT_RELATIONSHIPS));
		constraints.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ModelPackage.REQUIREMENT_CONSTRAINTS));
		this.goalDescription = (Description) XMLUtility.xmlInstance.deSerializeNode(root, ModelPackage.REQUIREMENT_GOAL_DESCRIPTION, this);
		this.endDescription.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ModelPackage.REQUIREMENT_END_DESCRIPTION));
	}
	
	@Override
	public String toString() {
		return name;
	}

	@Override
	public List<ConstraintConnection> getConstraintConnections() {
		return constraints; 
	}
}
